package com.ldn.controller.api;

import com.ldn.basic.dispose.exception.AppException;
import com.ldn.basic.enums.SMSSendEnums;
import com.ldn.basic.types.SMSCodeType;
import com.ldn.basic.utils.DateUtils;
import com.ldn.basic.utils.ali.ALiSmsUtils;
import com.ldn.basic.utils.cache.HutoolCacheUtils;

import java.util.Random;

/**
 * @author 李大牛家的牛 (scafel@163.com)
 * @createDate 2024/7/11 - 15:39
 * @description ...
 **/
public class SMSController {

    private static final int SMS_CODE_LENGTH = 6;
    private static final long SMS_CODE_TIMEOUT = 60 * 5;

    private static final String SMS_CODE_MIXED = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String SMS_CODE_DIGITAL = "0123456789";
    private static final String SMS_CODE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";


    public Boolean sendSMS(String phone, SMSSendEnums smsType) {
        String num = HutoolCacheUtils.get(smsType.getCodePrefix() + phone);
        if (num == null) {
            num = "0";
        }
        if (Integer.parseInt(num) > 6) {
            throw new AppException("今日发送短信验证码次数超过6次");
        }
        String smsCode = HutoolCacheUtils.get(smsType.getCodePrefix() + "code-" + phone);
        if (smsCode != null) {
            throw new AppException("短信验证码五分钟内有效，请稍后重新发送");
        }
        // 生成一个指定长度的短信验证码
        String code = generateSMSCode(SMS_CODE_LENGTH, SMSCodeType.SMS_CODE_DIGITAL);
        boolean sendRes = ALiSmsUtils.sendSMS(phone, code);
        if (sendRes){
            HutoolCacheUtils.setEx(smsType.getCodePrefix() + phone, String.valueOf(Integer.parseInt(num) + 1), DateUtils.getLeftSecondsTime());
            HutoolCacheUtils.setEx(smsType.getCodePrefix() + "code-" + phone, code, SMS_CODE_TIMEOUT);
        }
        return sendRes;
    }

    public Boolean validateSMSCode(String phone, String code, SMSSendEnums smsType) {
        String loginCode = HutoolCacheUtils.get(smsType.getCodePrefix() + "code-" + phone);
        if (loginCode == null) {
            throw new AppException("验证码已失效，请重新获取");
        }
        String validNum = HutoolCacheUtils.get(smsType.getCodePrefix() +" code-valid-" + phone);
        if (Integer.parseInt(validNum) > 6) {
            HutoolCacheUtils.delKey(smsType.getCodePrefix() + "code-" + phone);
            HutoolCacheUtils.delKey(smsType.getCodePrefix() +" code-valid-" + phone);
            throw new AppException("短信验证码验证次数超过多，请重新申请验证码");
        }
        if (!loginCode.equals(code)) {
            HutoolCacheUtils.setEx(smsType.getCodePrefix() +" code-valid-" + phone, String.valueOf(Integer.parseInt(validNum) + 1), DateUtils.getLeftSecondsTime());
            throw new AppException("验证码错误，请重新获取");
        }
        return true;
    }

    private String generateSMSCode(int length, SMSCodeType type) {
        String chars = "";
        switch (type) {
            case SMS_CODE_DIGITAL -> chars = SMS_CODE_DIGITAL;
            case SMS_CODE_LETTERS -> chars = SMS_CODE_LETTERS;
            default -> chars = SMS_CODE_MIXED;
        }
        Random random = new Random();
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        return sb.toString();
    }


}
